# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -amdgpu-global-isel-new-legality -mtriple=amdgcn-amd-amdhsa -mcpu=hawaii -run-pass=amdgpu-regbankselect %s -verify-machineinstrs -o - -regbankselect-fast | FileCheck %s
# RUN: llc -amdgpu-global-isel-new-legality -mtriple=amdgcn-amd-amdhsa -mcpu=hawaii -run-pass=amdgpu-regbankselect %s -verify-machineinstrs -o - -regbankselect-greedy | FileCheck %s

--- |
  define amdgpu_kernel void @load_global_v8i32_non_uniform(ptr addrspace(1) %in) {
    %tmp0 = call i32 @llvm.amdgcn.workitem.id.x() #0
    %global.not.uniform.v8i32 = getelementptr <8 x i32>, ptr addrspace(1) %in, i32 %tmp0
    %tmp2 = load <8 x i32>, ptr addrspace(1) %global.not.uniform.v8i32
    ret void
  }

  define amdgpu_kernel void @load_global_v4i64_non_uniform(ptr addrspace(1) %in) {
    %tmp0 = call i32 @llvm.amdgcn.workitem.id.x() #0
    %global.not.uniform.v4i64 = getelementptr <4 x i64>, ptr addrspace(1) %in, i32 %tmp0
    %tmp2 = load <4 x i64>, ptr addrspace(1) %global.not.uniform.v4i64
    ret void
  }
  define amdgpu_kernel void @load_global_v16i32_non_uniform(ptr addrspace(1) %in) {
    %tmp0 = call i32 @llvm.amdgcn.workitem.id.x() #0
    %global.not.uniform.v16i32 = getelementptr <16 x i32>, ptr addrspace(1) %in, i32 %tmp0
    %tmp2 = load <16 x i32>, ptr addrspace(1) %global.not.uniform.v16i32
    ret void
  }
  define amdgpu_kernel void @load_global_v8i64_non_uniform(ptr addrspace(1) %in) {
    %tmp0 = call i32 @llvm.amdgcn.workitem.id.x() #0
    %global.not.uniform.v8i64 = getelementptr <8 x i64>, ptr addrspace(1) %in, i32 %tmp0
    %tmp2 = load <8 x i64>, ptr addrspace(1) %global.not.uniform.v8i64
    ret void
  }
  define amdgpu_kernel void @load_global_v8i32_uniform() {ret void}
  define amdgpu_kernel void @load_global_v4i64_uniform() {ret void}
  define amdgpu_kernel void @load_global_v16i32_uniform() {ret void}
  define amdgpu_kernel void @load_global_v8i64_uniform() {ret void}
  define amdgpu_kernel void @load_constant_v8i32_non_uniform(ptr addrspace(4) %in) {
    %tmp0 = call i32 @llvm.amdgcn.workitem.id.x() #0
    %constant.not.uniform.v8i32 = getelementptr <8 x i32>, ptr addrspace(4) %in, i32 %tmp0
    %tmp2 = load <8 x i32>, ptr addrspace(4) %constant.not.uniform.v8i32
    ret void
  }

  define amdgpu_kernel void @load_constant_i256_non_uniform(ptr addrspace(4) %in) {
    %tmp0 = call i32 @llvm.amdgcn.workitem.id.x() #0
    %constant.not.uniform = getelementptr i256, ptr addrspace(4) %in, i32 %tmp0
    %tmp2 = load i256, ptr addrspace(4) %constant.not.uniform
    ret void
  }

  define amdgpu_kernel void @load_constant_v16i16_non_uniform(ptr addrspace(4) %in) {
    %tmp0 = call i32 @llvm.amdgcn.workitem.id.x() #0
    %constant.not.uniform = getelementptr <16 x i16>, ptr addrspace(4) %in, i32 %tmp0
    %tmp2 = load <16 x i16>, ptr addrspace(4) %constant.not.uniform
    ret void
  }

  define amdgpu_kernel void @load_constant_v4i64_non_uniform(ptr addrspace(4) %in) {
    %tmp0 = call i32 @llvm.amdgcn.workitem.id.x() #0
    %constant.not.uniform.v4i64 = getelementptr <4 x i64>, ptr addrspace(4) %in, i32 %tmp0
    %tmp2 = load <4 x i64>, ptr addrspace(4) %constant.not.uniform.v4i64
    ret void
  }
  define amdgpu_kernel void @load_constant_v16i32_non_uniform(ptr addrspace(4) %in) {
    %tmp0 = call i32 @llvm.amdgcn.workitem.id.x() #0
    %constant.not.uniform.v16i32 = getelementptr <16 x i32>, ptr addrspace(4) %in, i32 %tmp0
    %tmp2 = load <16 x i32>, ptr addrspace(4) %constant.not.uniform.v16i32
    ret void
  }
  define amdgpu_kernel void @load_constant_v8i64_non_uniform(ptr addrspace(4) %in) {
    %tmp0 = call i32 @llvm.amdgcn.workitem.id.x() #0
    %constant.not.uniform.v8i64 = getelementptr <8 x i64>, ptr addrspace(4) %in, i32 %tmp0
    %tmp2 = load <8 x i64>, ptr addrspace(4) %constant.not.uniform.v8i64
    ret void
  }

  define amdgpu_kernel void @load_constant_v8i32_uniform() {ret void}
  define amdgpu_kernel void @load_constant_v16i16_uniform() {ret void}
  define amdgpu_kernel void @load_constant_v4i64_uniform() {ret void}
  define amdgpu_kernel void @load_constant_v16i32_uniform() {ret void}
  define amdgpu_kernel void @load_constant_v8i64_uniform() {ret void}
  define amdgpu_kernel void @load_local_uniform() { ret void }
  define amdgpu_kernel void @load_region_uniform() { ret void }
  define amdgpu_kernel void @extload_constant_i8_to_i32_uniform() { ret void }
  define amdgpu_kernel void @extload_global_i8_to_i32_uniform() { ret void }
  define amdgpu_kernel void @extload_constant_i16_to_i32_uniform() { ret void }
  define amdgpu_kernel void @extload_global_i16_to_i32_uniform() { ret void }
  define amdgpu_kernel void @load_constant_i32_uniform_align4() {ret void}
  define amdgpu_kernel void @load_constant_i32_uniform_align2() {ret void}
  define amdgpu_kernel void @load_constant_i32_uniform_align1() {ret void}
  define amdgpu_kernel void @load_private_uniform_sgpr_i32() {ret void}
  define amdgpu_kernel void @load_constant_v8i32_vgpr_crash() { ret void }
  define amdgpu_kernel void @load_constant_v8i32_vgpr_crash_loop_phi() { ret void }

  define amdgpu_kernel void @load_constant_v3i32_align4() { ret void }
  define amdgpu_kernel void @load_constant_v3i32_align8() { ret void }
  define amdgpu_kernel void @load_constant_v3i32_align16() { ret void }

  define amdgpu_kernel void @load_constant_v6i16_align4() { ret void }
  define amdgpu_kernel void @load_constant_v6i16_align8() { ret void }
  define amdgpu_kernel void @load_constant_v6i16_align16() { ret void }

  define amdgpu_kernel void @load_constant_i96_align4() { ret void }
  define amdgpu_kernel void @load_constant_i96_align8() { ret void }
  define amdgpu_kernel void @load_constant_i96_align16() { ret void }

  declare i32 @llvm.amdgcn.workitem.id.x() #0
  attributes #0 = { nounwind readnone }
...

---
name: load_global_v8i32_non_uniform
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_global_v8i32_non_uniform
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p1) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr(p1) = COPY [[COPY]](p1)
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:vgpr(<4 x s32>) = G_LOAD [[COPY]](p1) :: (load (<4 x s32>) from %ir.global.not.uniform.v8i32, align 32, addrspace 1)
    ; CHECK-NEXT: [[C:%[0-9]+]]:vgpr(s64) = G_CONSTANT i64 16
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:vgpr(p1) = G_PTR_ADD [[COPY]], [[C]](s64)
    ; CHECK-NEXT: [[LOAD1:%[0-9]+]]:vgpr(<4 x s32>) = G_LOAD [[PTR_ADD]](p1) :: (load (<4 x s32>) from %ir.global.not.uniform.v8i32 + 16, basealign 32, addrspace 1)
    ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:vgpr(<8 x s32>) = G_CONCAT_VECTORS [[LOAD]](<4 x s32>), [[LOAD1]](<4 x s32>)
    %0:_(p1) = COPY $sgpr0_sgpr1
    %1:_(<8 x s32>) = G_LOAD %0 :: (load (<8 x s32>) from %ir.global.not.uniform.v8i32)
...

---
name: load_global_v4i64_non_uniform
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1

    ; CHECK-LABEL: name: load_global_v4i64_non_uniform
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p1) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr(p1) = COPY [[COPY]](p1)
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:vgpr(<2 x s64>) = G_LOAD [[COPY]](p1) :: (load (<2 x s64>) from %ir.global.not.uniform.v4i64, align 32, addrspace 1)
    ; CHECK-NEXT: [[C:%[0-9]+]]:vgpr(s64) = G_CONSTANT i64 16
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:vgpr(p1) = G_PTR_ADD [[COPY]], [[C]](s64)
    ; CHECK-NEXT: [[LOAD1:%[0-9]+]]:vgpr(<2 x s64>) = G_LOAD [[PTR_ADD]](p1) :: (load (<2 x s64>) from %ir.global.not.uniform.v4i64 + 16, basealign 32, addrspace 1)
    ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:vgpr(<4 x s64>) = G_CONCAT_VECTORS [[LOAD]](<2 x s64>), [[LOAD1]](<2 x s64>)
    %0:_(p1) = COPY $sgpr0_sgpr1
    %1:_(<4 x s64>) = G_LOAD %0 :: (load (<4 x s64>) from %ir.global.not.uniform.v4i64)
...

---
name: load_global_v16i32_non_uniform
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_global_v16i32_non_uniform
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p1) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr(p1) = COPY [[COPY]](p1)
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:vgpr(<4 x s32>) = G_LOAD [[COPY]](p1) :: (load (<4 x s32>) from %ir.global.not.uniform.v16i32, align 64, addrspace 1)
    ; CHECK-NEXT: [[C:%[0-9]+]]:vgpr(s64) = G_CONSTANT i64 16
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:vgpr(p1) = G_PTR_ADD [[COPY]], [[C]](s64)
    ; CHECK-NEXT: [[LOAD1:%[0-9]+]]:vgpr(<4 x s32>) = G_LOAD [[PTR_ADD]](p1) :: (load (<4 x s32>) from %ir.global.not.uniform.v16i32 + 16, basealign 64, addrspace 1)
    ; CHECK-NEXT: [[C1:%[0-9]+]]:vgpr(s64) = G_CONSTANT i64 32
    ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:vgpr(p1) = G_PTR_ADD [[COPY]], [[C1]](s64)
    ; CHECK-NEXT: [[LOAD2:%[0-9]+]]:vgpr(<4 x s32>) = G_LOAD [[PTR_ADD1]](p1) :: (load (<4 x s32>) from %ir.global.not.uniform.v16i32 + 32, align 32, basealign 64, addrspace 1)
    ; CHECK-NEXT: [[C2:%[0-9]+]]:vgpr(s64) = G_CONSTANT i64 48
    ; CHECK-NEXT: [[PTR_ADD2:%[0-9]+]]:vgpr(p1) = G_PTR_ADD [[COPY]], [[C2]](s64)
    ; CHECK-NEXT: [[LOAD3:%[0-9]+]]:vgpr(<4 x s32>) = G_LOAD [[PTR_ADD2]](p1) :: (load (<4 x s32>) from %ir.global.not.uniform.v16i32 + 48, basealign 64, addrspace 1)
    ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:vgpr(<16 x s32>) = G_CONCAT_VECTORS [[LOAD]](<4 x s32>), [[LOAD1]](<4 x s32>), [[LOAD2]](<4 x s32>), [[LOAD3]](<4 x s32>)
    %0:_(p1) = COPY $sgpr0_sgpr1
    %1:_(<16 x s32>) = G_LOAD %0 :: (load (<16 x s32>) from %ir.global.not.uniform.v16i32)
...

---
name: load_global_v8i64_non_uniform
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_global_v8i64_non_uniform
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p1) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr(p1) = COPY [[COPY]](p1)
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:vgpr(<2 x s64>) = G_LOAD [[COPY]](p1) :: (load (<2 x s64>) from %ir.global.not.uniform.v8i64, align 64, addrspace 1)
    ; CHECK-NEXT: [[C:%[0-9]+]]:vgpr(s64) = G_CONSTANT i64 16
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:vgpr(p1) = G_PTR_ADD [[COPY]], [[C]](s64)
    ; CHECK-NEXT: [[LOAD1:%[0-9]+]]:vgpr(<2 x s64>) = G_LOAD [[PTR_ADD]](p1) :: (load (<2 x s64>) from %ir.global.not.uniform.v8i64 + 16, basealign 64, addrspace 1)
    ; CHECK-NEXT: [[C1:%[0-9]+]]:vgpr(s64) = G_CONSTANT i64 32
    ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:vgpr(p1) = G_PTR_ADD [[COPY]], [[C1]](s64)
    ; CHECK-NEXT: [[LOAD2:%[0-9]+]]:vgpr(<2 x s64>) = G_LOAD [[PTR_ADD1]](p1) :: (load (<2 x s64>) from %ir.global.not.uniform.v8i64 + 32, align 32, basealign 64, addrspace 1)
    ; CHECK-NEXT: [[C2:%[0-9]+]]:vgpr(s64) = G_CONSTANT i64 48
    ; CHECK-NEXT: [[PTR_ADD2:%[0-9]+]]:vgpr(p1) = G_PTR_ADD [[COPY]], [[C2]](s64)
    ; CHECK-NEXT: [[LOAD3:%[0-9]+]]:vgpr(<2 x s64>) = G_LOAD [[PTR_ADD2]](p1) :: (load (<2 x s64>) from %ir.global.not.uniform.v8i64 + 48, basealign 64, addrspace 1)
    ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:vgpr(<8 x s64>) = G_CONCAT_VECTORS [[LOAD]](<2 x s64>), [[LOAD1]](<2 x s64>), [[LOAD2]](<2 x s64>), [[LOAD3]](<2 x s64>)
    %0:_(p1) = COPY $sgpr0_sgpr1
    %1:_(<8 x s64>) = G_LOAD %0 :: (load (<8 x s64>) from %ir.global.not.uniform.v8i64)
...

---
name: load_global_v8i32_uniform
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_global_v8i32_uniform
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p1) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:sgpr(<8 x s32>) = G_LOAD [[COPY]](p1) :: (invariant load (<8 x s32>), addrspace 1)
    %0:_(p1) = COPY $sgpr0_sgpr1
    %1:_(<8 x s32>) = G_LOAD %0 :: (invariant load (<8 x s32>), addrspace 1)
...

---
name: load_global_v4i64_uniform
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_global_v4i64_uniform
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p1) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:sgpr(<4 x s64>) = G_LOAD [[COPY]](p1) :: (invariant load (<4 x s64>), addrspace 1)
    %0:_(p1) = COPY $sgpr0_sgpr1
    %1:_(<4 x s64>) = G_LOAD %0 :: (invariant load (<4 x s64>), addrspace 1)
...

---
name: load_global_v16i32_uniform
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_global_v16i32_uniform
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p1) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:sgpr(<16 x s32>) = G_LOAD [[COPY]](p1) :: (invariant load (<16 x s32>), addrspace 1)
    %0:_(p1) = COPY $sgpr0_sgpr1
    %1:_(<16 x s32>) = G_LOAD %0 :: (invariant load (<16 x s32>), addrspace 1)
...

---
name: load_global_v8i64_uniform
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_global_v8i64_uniform
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p1) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:sgpr(<8 x s64>) = G_LOAD [[COPY]](p1) :: (invariant load (<8 x s64>), addrspace 1)
    %0:_(p1) = COPY $sgpr0_sgpr1
    %1:_(<8 x s64>) = G_LOAD %0 :: (invariant load (<8 x s64>), addrspace 1)
...

---
name: load_constant_v8i32_non_uniform
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_constant_v8i32_non_uniform
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr(p4) = COPY [[COPY]](p4)
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:vgpr(<4 x s32>) = G_LOAD [[COPY]](p4) :: (load (<4 x s32>) from %ir.constant.not.uniform.v8i32, align 32, addrspace 4)
    ; CHECK-NEXT: [[C:%[0-9]+]]:vgpr(s64) = G_CONSTANT i64 16
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:vgpr(p4) = G_PTR_ADD [[COPY]], [[C]](s64)
    ; CHECK-NEXT: [[LOAD1:%[0-9]+]]:vgpr(<4 x s32>) = G_LOAD [[PTR_ADD]](p4) :: (load (<4 x s32>) from %ir.constant.not.uniform.v8i32 + 16, basealign 32, addrspace 4)
    ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:vgpr(<8 x s32>) = G_CONCAT_VECTORS [[LOAD]](<4 x s32>), [[LOAD1]](<4 x s32>)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(<8 x s32>) = G_LOAD %0 :: (load (<8 x s32>) from %ir.constant.not.uniform.v8i32)
...

---
name: load_constant_i256_non_uniform
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_constant_i256_non_uniform
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr(p4) = COPY [[COPY]](p4)
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:vgpr(s128) = G_LOAD [[COPY]](p4) :: (load (s128) from %ir.constant.not.uniform, align 32, addrspace 4)
    ; CHECK-NEXT: [[C:%[0-9]+]]:vgpr(s64) = G_CONSTANT i64 16
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:vgpr(p4) = G_PTR_ADD [[COPY]], [[C]](s64)
    ; CHECK-NEXT: [[LOAD1:%[0-9]+]]:vgpr(s128) = G_LOAD [[PTR_ADD]](p4) :: (load (s128) from %ir.constant.not.uniform + 16, basealign 32, addrspace 4)
    ; CHECK-NEXT: [[MV:%[0-9]+]]:vgpr(s256) = G_MERGE_VALUES [[LOAD]](s128), [[LOAD1]](s128)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(s256) = G_LOAD %0 :: (load (s256) from %ir.constant.not.uniform)
...

---
name: load_constant_v16i16_non_uniform
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1

    ; CHECK-LABEL: name: load_constant_v16i16_non_uniform
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr(p4) = COPY [[COPY]](p4)
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:vgpr(<8 x s16>) = G_LOAD [[COPY]](p4) :: (load (<8 x s16>) from %ir.constant.not.uniform, align 32, addrspace 4)
    ; CHECK-NEXT: [[C:%[0-9]+]]:vgpr(s64) = G_CONSTANT i64 16
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:vgpr(p4) = G_PTR_ADD [[COPY]], [[C]](s64)
    ; CHECK-NEXT: [[LOAD1:%[0-9]+]]:vgpr(<8 x s16>) = G_LOAD [[PTR_ADD]](p4) :: (load (<8 x s16>) from %ir.constant.not.uniform + 16, basealign 32, addrspace 4)
    ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:vgpr(<16 x s16>) = G_CONCAT_VECTORS [[LOAD]](<8 x s16>), [[LOAD1]](<8 x s16>)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(<16 x s16>) = G_LOAD %0 :: (load (<16 x s16>) from %ir.constant.not.uniform)
...

---
name: load_constant_v4i64_non_uniform
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_constant_v4i64_non_uniform
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr(p4) = COPY [[COPY]](p4)
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:vgpr(<2 x s64>) = G_LOAD [[COPY]](p4) :: (load (<2 x s64>) from %ir.constant.not.uniform.v4i64, align 32, addrspace 4)
    ; CHECK-NEXT: [[C:%[0-9]+]]:vgpr(s64) = G_CONSTANT i64 16
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:vgpr(p4) = G_PTR_ADD [[COPY]], [[C]](s64)
    ; CHECK-NEXT: [[LOAD1:%[0-9]+]]:vgpr(<2 x s64>) = G_LOAD [[PTR_ADD]](p4) :: (load (<2 x s64>) from %ir.constant.not.uniform.v4i64 + 16, basealign 32, addrspace 4)
    ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:vgpr(<4 x s64>) = G_CONCAT_VECTORS [[LOAD]](<2 x s64>), [[LOAD1]](<2 x s64>)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(<4 x s64>) = G_LOAD %0 :: (load (<4 x s64>) from %ir.constant.not.uniform.v4i64)
...

---
name: load_constant_v16i32_non_uniform
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_constant_v16i32_non_uniform
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr(p4) = COPY [[COPY]](p4)
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:vgpr(<4 x s32>) = G_LOAD [[COPY]](p4) :: (load (<4 x s32>) from %ir.constant.not.uniform.v16i32, align 64, addrspace 4)
    ; CHECK-NEXT: [[C:%[0-9]+]]:vgpr(s64) = G_CONSTANT i64 16
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:vgpr(p4) = G_PTR_ADD [[COPY]], [[C]](s64)
    ; CHECK-NEXT: [[LOAD1:%[0-9]+]]:vgpr(<4 x s32>) = G_LOAD [[PTR_ADD]](p4) :: (load (<4 x s32>) from %ir.constant.not.uniform.v16i32 + 16, basealign 64, addrspace 4)
    ; CHECK-NEXT: [[C1:%[0-9]+]]:vgpr(s64) = G_CONSTANT i64 32
    ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:vgpr(p4) = G_PTR_ADD [[COPY]], [[C1]](s64)
    ; CHECK-NEXT: [[LOAD2:%[0-9]+]]:vgpr(<4 x s32>) = G_LOAD [[PTR_ADD1]](p4) :: (load (<4 x s32>) from %ir.constant.not.uniform.v16i32 + 32, align 32, basealign 64, addrspace 4)
    ; CHECK-NEXT: [[C2:%[0-9]+]]:vgpr(s64) = G_CONSTANT i64 48
    ; CHECK-NEXT: [[PTR_ADD2:%[0-9]+]]:vgpr(p4) = G_PTR_ADD [[COPY]], [[C2]](s64)
    ; CHECK-NEXT: [[LOAD3:%[0-9]+]]:vgpr(<4 x s32>) = G_LOAD [[PTR_ADD2]](p4) :: (load (<4 x s32>) from %ir.constant.not.uniform.v16i32 + 48, basealign 64, addrspace 4)
    ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:vgpr(<16 x s32>) = G_CONCAT_VECTORS [[LOAD]](<4 x s32>), [[LOAD1]](<4 x s32>), [[LOAD2]](<4 x s32>), [[LOAD3]](<4 x s32>)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(<16 x s32>) = G_LOAD %0 :: (load (<16 x s32>) from %ir.constant.not.uniform.v16i32)
...

---
name: load_constant_v8i64_non_uniform
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_constant_v8i64_non_uniform
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr(p4) = COPY [[COPY]](p4)
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:vgpr(<2 x s64>) = G_LOAD [[COPY]](p4) :: (load (<2 x s64>) from %ir.constant.not.uniform.v8i64, align 64, addrspace 4)
    ; CHECK-NEXT: [[C:%[0-9]+]]:vgpr(s64) = G_CONSTANT i64 16
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:vgpr(p4) = G_PTR_ADD [[COPY]], [[C]](s64)
    ; CHECK-NEXT: [[LOAD1:%[0-9]+]]:vgpr(<2 x s64>) = G_LOAD [[PTR_ADD]](p4) :: (load (<2 x s64>) from %ir.constant.not.uniform.v8i64 + 16, basealign 64, addrspace 4)
    ; CHECK-NEXT: [[C1:%[0-9]+]]:vgpr(s64) = G_CONSTANT i64 32
    ; CHECK-NEXT: [[PTR_ADD1:%[0-9]+]]:vgpr(p4) = G_PTR_ADD [[COPY]], [[C1]](s64)
    ; CHECK-NEXT: [[LOAD2:%[0-9]+]]:vgpr(<2 x s64>) = G_LOAD [[PTR_ADD1]](p4) :: (load (<2 x s64>) from %ir.constant.not.uniform.v8i64 + 32, align 32, basealign 64, addrspace 4)
    ; CHECK-NEXT: [[C2:%[0-9]+]]:vgpr(s64) = G_CONSTANT i64 48
    ; CHECK-NEXT: [[PTR_ADD2:%[0-9]+]]:vgpr(p4) = G_PTR_ADD [[COPY]], [[C2]](s64)
    ; CHECK-NEXT: [[LOAD3:%[0-9]+]]:vgpr(<2 x s64>) = G_LOAD [[PTR_ADD2]](p4) :: (load (<2 x s64>) from %ir.constant.not.uniform.v8i64 + 48, basealign 64, addrspace 4)
    ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:vgpr(<8 x s64>) = G_CONCAT_VECTORS [[LOAD]](<2 x s64>), [[LOAD1]](<2 x s64>), [[LOAD2]](<2 x s64>), [[LOAD3]](<2 x s64>)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(<8 x s64>) = G_LOAD %0 :: (load (<8 x s64>) from %ir.constant.not.uniform.v8i64)
...

---
name: load_constant_v8i32_uniform
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_constant_v8i32_uniform
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:sgpr(<8 x s32>) = G_LOAD [[COPY]](p4) :: (load (<8 x s32>), addrspace 4)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(<8 x s32>) = G_LOAD %0 :: (load (<8 x s32>), addrspace 4)
...

---
name: load_constant_v16i16_uniform
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_constant_v16i16_uniform
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:sgpr(<16 x s16>) = G_LOAD [[COPY]](p4) :: (load (<16 x s16>), addrspace 4)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(<16 x s16>) = G_LOAD %0 :: (load (<16 x s16>), addrspace 4)
...

---
name: load_constant_v4i64_uniform
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_constant_v4i64_uniform
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:sgpr(<4 x s64>) = G_LOAD [[COPY]](p4) :: (load (<4 x s64>), addrspace 4)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(<4 x s64>) = G_LOAD %0 :: (load (<4 x s64>), addrspace 4)
...

---
name: load_constant_v16i32_uniform
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_constant_v16i32_uniform
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:sgpr(<16 x s32>) = G_LOAD [[COPY]](p4) :: (load (<16 x s32>), addrspace 4)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(<16 x s32>) = G_LOAD %0 :: (load (<16 x s32>), addrspace 4)
...

---
name: load_constant_v8i64_uniform
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_constant_v8i64_uniform
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:sgpr(<8 x s64>) = G_LOAD [[COPY]](p4) :: (load (<8 x s64>), addrspace 4)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(<8 x s64>) = G_LOAD %0 :: (load (<8 x s64>), addrspace 4)
...

---
name: load_local_uniform
legalized: true
body: |
  bb.0:
    liveins: $sgpr0

    ; CHECK-LABEL: name: load_local_uniform
    ; CHECK: liveins: $sgpr0
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p3) = COPY $sgpr0
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr(p3) = COPY [[COPY]](p3)
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:vgpr(s32) = G_LOAD [[COPY1]](p3) :: (load (s32), addrspace 3)
    %0:_(p3) = COPY $sgpr0
    %1:_(s32) = G_LOAD %0 :: (load (s32), addrspace 3)

...
---
name: load_region_uniform
legalized: true
body: |
  bb.0:
    liveins: $sgpr0

    ; CHECK-LABEL: name: load_region_uniform
    ; CHECK: liveins: $sgpr0
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p3) = COPY $sgpr0
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr(p3) = COPY [[COPY]](p3)
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:vgpr(s32) = G_LOAD [[COPY1]](p3) :: (load (s32), addrspace 5)
    %0:_(p3) = COPY $sgpr0
    %1:_(s32) = G_LOAD %0 :: (load (s32), addrspace 5)

...

---
name: extload_constant_i8_to_i32_uniform
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: extload_constant_i8_to_i32_uniform
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr(p4) = COPY [[COPY]](p4)
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:vgpr(s32) = G_LOAD [[COPY1]](p4) :: (load (s8), addrspace 4)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(s32) = G_LOAD %0 :: (load (s8), addrspace 4, align 1)
...

---
name: extload_global_i8_to_i32_uniform
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1

    ; CHECK-LABEL: name: extload_global_i8_to_i32_uniform
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr(p4) = COPY [[COPY]](p4)
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:vgpr(s32) = G_LOAD [[COPY1]](p4) :: (load (s8), addrspace 1)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(s32) = G_LOAD %0 :: (load (s8), addrspace 1, align 1)
...

---
name: extload_constant_i16_to_i32_uniform
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1

    ; CHECK-LABEL: name: extload_constant_i16_to_i32_uniform
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr(p4) = COPY [[COPY]](p4)
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:vgpr(s32) = G_LOAD [[COPY1]](p4) :: (load (s16), addrspace 4)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(s32) = G_LOAD %0 :: (load (s16), addrspace 4, align 2)
...

---
name: extload_global_i16_to_i32_uniform
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1

    ; CHECK-LABEL: name: extload_global_i16_to_i32_uniform
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr(p4) = COPY [[COPY]](p4)
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:vgpr(s32) = G_LOAD [[COPY1]](p4) :: (load (s16), addrspace 1)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(s32) = G_LOAD %0 :: (load (s16), addrspace 1, align 2)
...

---
name: load_constant_i32_uniform_align4
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_constant_i32_uniform_align4
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:sgpr(s32) = G_LOAD [[COPY]](p4) :: (load (s32), addrspace 4)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(s32) = G_LOAD %0 :: (load (s32), addrspace 4, align 4)
...

---
name: load_constant_i32_uniform_align2
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1

    ; CHECK-LABEL: name: load_constant_i32_uniform_align2
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr(p4) = COPY [[COPY]](p4)
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:vgpr(s32) = G_LOAD [[COPY1]](p4) :: (load (s32), align 2, addrspace 4)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(s32) = G_LOAD %0 :: (load (s32), addrspace 4, align 2)
...

---
name: load_constant_i32_uniform_align1
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1

    ; CHECK-LABEL: name: load_constant_i32_uniform_align1
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr(p4) = COPY [[COPY]](p4)
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:vgpr(s32) = G_LOAD [[COPY1]](p4) :: (load (s32), align 1, addrspace 4)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(s32) = G_LOAD %0 :: (load (s32), addrspace 4, align 1)
...

---
name: load_private_uniform_sgpr_i32
legalized: true

body: |
  bb.0:
    liveins: $sgpr0

    ; CHECK-LABEL: name: load_private_uniform_sgpr_i32
    ; CHECK: liveins: $sgpr0
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p5) = COPY $sgpr0
    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:vgpr(p5) = COPY [[COPY]](p5)
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:vgpr(s32) = G_LOAD [[COPY1]](p5) :: (load (s32), addrspace 5)
    %0:_(p5) = COPY $sgpr0
    %1:_(s32) = G_LOAD %0 :: (load (s32), addrspace 5, align 4)
...

---
name: load_constant_v8i32_vgpr_crash
legalized: true
tracksRegLiveness: true

body: |
  bb.0:
    liveins: $vgpr0_vgpr1

    ; CHECK-LABEL: name: load_constant_v8i32_vgpr_crash
    ; CHECK: liveins: $vgpr0_vgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:vgpr(p4) = COPY $vgpr0_vgpr1
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:vgpr(<4 x s32>) = G_LOAD [[COPY]](p4) :: (load (<4 x s32>), align 32, addrspace 4)
    ; CHECK-NEXT: [[C:%[0-9]+]]:vgpr(s64) = G_CONSTANT i64 16
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:vgpr(p4) = G_PTR_ADD [[COPY]], [[C]](s64)
    ; CHECK-NEXT: [[LOAD1:%[0-9]+]]:vgpr(<4 x s32>) = G_LOAD [[PTR_ADD]](p4) :: (load (<4 x s32>) from unknown-address + 16, addrspace 4)
    ; CHECK-NEXT: [[CONCAT_VECTORS:%[0-9]+]]:vgpr(<8 x s32>) = G_CONCAT_VECTORS [[LOAD]](<4 x s32>), [[LOAD1]](<4 x s32>)
    %0:_(p4) = COPY $vgpr0_vgpr1
    %1:_(<8 x s32>) = G_LOAD %0 :: (load (<8 x s32>), addrspace 4)
...

---
name: load_constant_v8i32_vgpr_crash_loop_phi
legalized: true
tracksRegLiveness: true

body: |
  ; CHECK-LABEL: name: load_constant_v8i32_vgpr_crash_loop_phi
  ; CHECK: bb.0:
  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
  ; CHECK-NEXT:   liveins: $sgpr0_sgpr1, $sgpr2_sgpr3
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:sgpr(p4) = COPY $sgpr2_sgpr3
  ; CHECK-NEXT:   G_BR %bb.1
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT: bb.1:
  ; CHECK-NEXT:   successors: %bb.1(0x80000000)
  ; CHECK-NEXT: {{  $}}
  ; CHECK-NEXT:   [[PHI:%[0-9]+]]:vgpr(p4) = G_PHI [[COPY]](p4), %bb.0, %3(p4), %bb.1
  ; CHECK-NEXT:   [[LOAD:%[0-9]+]]:vgpr(<4 x s32>) = G_LOAD [[PHI]](p4) :: (load (<4 x s32>), align 32, addrspace 4)
  ; CHECK-NEXT:   [[C:%[0-9]+]]:vgpr(s64) = G_CONSTANT i64 16
  ; CHECK-NEXT:   [[PTR_ADD:%[0-9]+]]:vgpr(p4) = G_PTR_ADD [[PHI]], [[C]](s64)
  ; CHECK-NEXT:   [[LOAD1:%[0-9]+]]:vgpr(<4 x s32>) = G_LOAD [[PTR_ADD]](p4) :: (load (<4 x s32>) from unknown-address + 16, addrspace 4)
  ; CHECK-NEXT:   [[CONCAT_VECTORS:%[0-9]+]]:vgpr(<8 x s32>) = G_CONCAT_VECTORS [[LOAD]](<4 x s32>), [[LOAD1]](<4 x s32>)
  ; CHECK-NEXT:   [[COPY2:%[0-9]+]]:sgpr(p4) = COPY [[COPY1]](p4)
  ; CHECK-NEXT:   G_BR %bb.1
  bb.0:
    liveins: $sgpr0_sgpr1, $sgpr2_sgpr3


    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(p4) = COPY $sgpr2_sgpr3
    G_BR %bb.1

  bb.1:
    %2:_(p4) = G_PHI %0, %bb.0, %4, %bb.1
    %3:_(<8 x s32>) = G_LOAD %2 :: (load (<8 x s32>), addrspace 4)
    %4:_(p4) = COPY %1
    G_BR %bb.1
...

---
name: load_constant_v3i32_align4
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_constant_v3i32_align4
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:sgpr(<2 x s32>) = G_LOAD [[COPY]](p4) :: (invariant load (<2 x s32>), align 4, addrspace 4)
    ; CHECK-NEXT: [[C:%[0-9]+]]:sgpr(s64) = G_CONSTANT i64 8
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:sgpr(p4) = G_PTR_ADD [[COPY]], [[C]](s64)
    ; CHECK-NEXT: [[LOAD1:%[0-9]+]]:sgpr(s32) = G_LOAD [[PTR_ADD]](p4) :: (invariant load (s32) from unknown-address + 8, addrspace 4)
    ; CHECK-NEXT: [[UV:%[0-9]+]]:sgpr(s32), [[UV1:%[0-9]+]]:sgpr(s32) = G_UNMERGE_VALUES [[LOAD]](<2 x s32>)
    ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:sgpr(<3 x s32>) = G_BUILD_VECTOR [[UV]](s32), [[UV1]](s32), [[LOAD1]](s32)
    ; CHECK-NEXT: S_ENDPGM 0, implicit [[BUILD_VECTOR]](<3 x s32>)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(<3 x s32>) = G_LOAD %0 :: (invariant load (<3 x s32>), addrspace 4, align 4)
    S_ENDPGM 0, implicit %1
...

---
name: load_constant_v3i32_align8
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_constant_v3i32_align8
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:sgpr(<2 x s32>) = G_LOAD [[COPY]](p4) :: (invariant load (<2 x s32>), addrspace 4)
    ; CHECK-NEXT: [[C:%[0-9]+]]:sgpr(s64) = G_CONSTANT i64 8
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:sgpr(p4) = G_PTR_ADD [[COPY]], [[C]](s64)
    ; CHECK-NEXT: [[LOAD1:%[0-9]+]]:sgpr(s32) = G_LOAD [[PTR_ADD]](p4) :: (invariant load (s32) from unknown-address + 8, align 8, addrspace 4)
    ; CHECK-NEXT: [[UV:%[0-9]+]]:sgpr(s32), [[UV1:%[0-9]+]]:sgpr(s32) = G_UNMERGE_VALUES [[LOAD]](<2 x s32>)
    ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:sgpr(<3 x s32>) = G_BUILD_VECTOR [[UV]](s32), [[UV1]](s32), [[LOAD1]](s32)
    ; CHECK-NEXT: S_ENDPGM 0, implicit [[BUILD_VECTOR]](<3 x s32>)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(<3 x s32>) = G_LOAD %0 :: (invariant load (<3 x s32>), addrspace 4, align 8)
    S_ENDPGM 0, implicit %1
...

---
name: load_constant_v3i32_align16
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_constant_v3i32_align16
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:sgpr(<4 x s32>) = G_LOAD [[COPY]](p4) :: (invariant load (<4 x s32>), addrspace 4)
    ; CHECK-NEXT: [[UV:%[0-9]+]]:sgpr(s32), [[UV1:%[0-9]+]]:sgpr(s32), [[UV2:%[0-9]+]]:sgpr(s32), [[UV3:%[0-9]+]]:sgpr(s32) = G_UNMERGE_VALUES [[LOAD]](<4 x s32>)
    ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:sgpr(<3 x s32>) = G_BUILD_VECTOR [[UV]](s32), [[UV1]](s32), [[UV2]](s32)
    ; CHECK-NEXT: S_ENDPGM 0, implicit [[BUILD_VECTOR]](<3 x s32>)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(<3 x s32>) = G_LOAD %0 :: (invariant load (<3 x s32>), addrspace 4, align 16)
    S_ENDPGM 0, implicit %1
...

---
name: load_constant_v6i16_align4
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_constant_v6i16_align4
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:sgpr(<4 x s16>) = G_LOAD [[COPY]](p4) :: (invariant load (<4 x s16>), align 4, addrspace 4)
    ; CHECK-NEXT: [[C:%[0-9]+]]:sgpr(s64) = G_CONSTANT i64 8
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:sgpr(p4) = G_PTR_ADD [[COPY]], [[C]](s64)
    ; CHECK-NEXT: [[LOAD1:%[0-9]+]]:sgpr(<2 x s16>) = G_LOAD [[PTR_ADD]](p4) :: (invariant load (<2 x s16>) from unknown-address + 8, addrspace 4)
    ; CHECK-NEXT: [[UV:%[0-9]+]]:sgpr(s16), [[UV1:%[0-9]+]]:sgpr(s16), [[UV2:%[0-9]+]]:sgpr(s16), [[UV3:%[0-9]+]]:sgpr(s16) = G_UNMERGE_VALUES [[LOAD]](<4 x s16>)
    ; CHECK-NEXT: [[UV4:%[0-9]+]]:sgpr(s16), [[UV5:%[0-9]+]]:sgpr(s16) = G_UNMERGE_VALUES [[LOAD1]](<2 x s16>)
    ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:sgpr(<6 x s16>) = G_BUILD_VECTOR [[UV]](s16), [[UV1]](s16), [[UV2]](s16), [[UV3]](s16), [[UV4]](s16), [[UV5]](s16)
    ; CHECK-NEXT: S_ENDPGM 0, implicit [[BUILD_VECTOR]](<6 x s16>)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(<6 x s16>) = G_LOAD %0 :: (invariant load (<6 x s16>), addrspace 4, align 4)
    S_ENDPGM 0, implicit %1
...

---
name: load_constant_v6i16_align8
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_constant_v6i16_align8
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:sgpr(<4 x s16>) = G_LOAD [[COPY]](p4) :: (invariant load (<4 x s16>), addrspace 4)
    ; CHECK-NEXT: [[C:%[0-9]+]]:sgpr(s64) = G_CONSTANT i64 8
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:sgpr(p4) = G_PTR_ADD [[COPY]], [[C]](s64)
    ; CHECK-NEXT: [[LOAD1:%[0-9]+]]:sgpr(<2 x s16>) = G_LOAD [[PTR_ADD]](p4) :: (invariant load (<2 x s16>) from unknown-address + 8, align 8, addrspace 4)
    ; CHECK-NEXT: [[UV:%[0-9]+]]:sgpr(s16), [[UV1:%[0-9]+]]:sgpr(s16), [[UV2:%[0-9]+]]:sgpr(s16), [[UV3:%[0-9]+]]:sgpr(s16) = G_UNMERGE_VALUES [[LOAD]](<4 x s16>)
    ; CHECK-NEXT: [[UV4:%[0-9]+]]:sgpr(s16), [[UV5:%[0-9]+]]:sgpr(s16) = G_UNMERGE_VALUES [[LOAD1]](<2 x s16>)
    ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:sgpr(<6 x s16>) = G_BUILD_VECTOR [[UV]](s16), [[UV1]](s16), [[UV2]](s16), [[UV3]](s16), [[UV4]](s16), [[UV5]](s16)
    ; CHECK-NEXT: S_ENDPGM 0, implicit [[BUILD_VECTOR]](<6 x s16>)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(<6 x s16>) = G_LOAD %0 :: (invariant load (<6 x s16>), addrspace 4, align 8)
    S_ENDPGM 0, implicit %1
...

---
name: load_constant_v6i16_align16
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_constant_v6i16_align16
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:sgpr(<8 x s16>) = G_LOAD [[COPY]](p4) :: (invariant load (<8 x s16>), addrspace 4)
    ; CHECK-NEXT: [[UV:%[0-9]+]]:sgpr(s16), [[UV1:%[0-9]+]]:sgpr(s16), [[UV2:%[0-9]+]]:sgpr(s16), [[UV3:%[0-9]+]]:sgpr(s16), [[UV4:%[0-9]+]]:sgpr(s16), [[UV5:%[0-9]+]]:sgpr(s16), [[UV6:%[0-9]+]]:sgpr(s16), [[UV7:%[0-9]+]]:sgpr(s16) = G_UNMERGE_VALUES [[LOAD]](<8 x s16>)
    ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:sgpr(<6 x s16>) = G_BUILD_VECTOR [[UV]](s16), [[UV1]](s16), [[UV2]](s16), [[UV3]](s16), [[UV4]](s16), [[UV5]](s16)
    ; CHECK-NEXT: S_ENDPGM 0, implicit [[BUILD_VECTOR]](<6 x s16>)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(<6 x s16>) = G_LOAD %0 :: (invariant load (<6 x s16>), addrspace 4, align 16)
    S_ENDPGM 0, implicit %1
...

---
name: load_constant_i96_align4
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_constant_i96_align4
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:sgpr(s64) = G_LOAD [[COPY]](p4) :: (invariant load (s64), align 4, addrspace 4)
    ; CHECK-NEXT: [[C:%[0-9]+]]:sgpr(s64) = G_CONSTANT i64 8
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:sgpr(p4) = G_PTR_ADD [[COPY]], [[C]](s64)
    ; CHECK-NEXT: [[LOAD1:%[0-9]+]]:sgpr(s32) = G_LOAD [[PTR_ADD]](p4) :: (invariant load (s32) from unknown-address + 8, addrspace 4)
    ; CHECK-NEXT: [[UV:%[0-9]+]]:sgpr(s32), [[UV1:%[0-9]+]]:sgpr(s32) = G_UNMERGE_VALUES [[LOAD]](s64)
    ; CHECK-NEXT: [[MV:%[0-9]+]]:sgpr(s96) = G_MERGE_VALUES [[UV]](s32), [[UV1]](s32), [[LOAD1]](s32)
    ; CHECK-NEXT: S_ENDPGM 0, implicit [[MV]](s96)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(s96) = G_LOAD %0 :: (invariant load (s96), addrspace 4, align 4)
    S_ENDPGM 0, implicit %1
...

---
name: load_constant_i96_align8
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_constant_i96_align8
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:sgpr(s64) = G_LOAD [[COPY]](p4) :: (invariant load (s64), addrspace 4)
    ; CHECK-NEXT: [[C:%[0-9]+]]:sgpr(s64) = G_CONSTANT i64 8
    ; CHECK-NEXT: [[PTR_ADD:%[0-9]+]]:sgpr(p4) = G_PTR_ADD [[COPY]], [[C]](s64)
    ; CHECK-NEXT: [[LOAD1:%[0-9]+]]:sgpr(s32) = G_LOAD [[PTR_ADD]](p4) :: (invariant load (s32) from unknown-address + 8, align 8, addrspace 4)
    ; CHECK-NEXT: [[UV:%[0-9]+]]:sgpr(s32), [[UV1:%[0-9]+]]:sgpr(s32) = G_UNMERGE_VALUES [[LOAD]](s64)
    ; CHECK-NEXT: [[MV:%[0-9]+]]:sgpr(s96) = G_MERGE_VALUES [[UV]](s32), [[UV1]](s32), [[LOAD1]](s32)
    ; CHECK-NEXT: S_ENDPGM 0, implicit [[MV]](s96)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(s96) = G_LOAD %0 :: (invariant load (s96), addrspace 4, align 8)
    S_ENDPGM 0, implicit %1
...

---
name: load_constant_i96_align16
legalized: true

body: |
  bb.0:
    liveins: $sgpr0_sgpr1
    ; CHECK-LABEL: name: load_constant_i96_align16
    ; CHECK: liveins: $sgpr0_sgpr1
    ; CHECK-NEXT: {{  $}}
    ; CHECK-NEXT: [[COPY:%[0-9]+]]:sgpr(p4) = COPY $sgpr0_sgpr1
    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:sgpr(s128) = G_LOAD [[COPY]](p4) :: (invariant load (s128), addrspace 4)
    ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:sgpr(s96) = G_TRUNC [[LOAD]](s128)
    ; CHECK-NEXT: S_ENDPGM 0, implicit [[TRUNC]](s96)
    %0:_(p4) = COPY $sgpr0_sgpr1
    %1:_(s96) = G_LOAD %0 :: (invariant load (s96), addrspace 4, align 16)
    S_ENDPGM 0, implicit %1
...
